using ADODB;
using System;
using COMAdmin;
using System.IO;
using System.Xml;
using System.Text;
using System.Data;
using Microsoft.Win32;
using System.Threading;
using System.Management;
using System.Collections;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.DirectoryServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using Microsoft.Interop.Security.AzRoles;
using Microsoft.CommerceServer.Interop.Configuration;

namespace Microsoft.CommerceServer.SecureSite
{
	/// <summary>
	/// Summary description for CommerceSecurityInfo.
	/// </summary>
	public class CommerceSecurityInfo
	{
		[DllImport("advapi32.dll", SetLastError=true)]
		public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

		[DllImport("kernel32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]
		private unsafe static extern int FormatMessage(int dwFlags, ref IntPtr lpSource, int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr *Arguments);

		[DllImport("kernel32.dll")]
		public static extern Boolean AllocConsole();
		[DllImport("kernel32.dll")]
		public static extern Boolean FreeConsole();

		private static Hashtable _forms;
		public static string SiteName;
		public static string Domain;
		public static string Password;
		public static string Username;
		public static DataSet CatalogWebServiceRole;
		public static DataSet MarketingWebServiceRole;
        public static DataSet ProfilesWebServiceRole;
        public static DataSet OrdersWebServiceRole;
		public static string ApplicationPoolName;
		public static bool NewApplicationPool = true;
		public static bool IsDirty = false;
		public static GlobalConfig2FreeThreaded glb2 = new GlobalConfig2FreeThreaded();
		public static SiteConfigReadOnlyFreeThreaded sitecfg = new SiteConfigReadOnlyFreeThreaded();
		public static System.Array ary;
		public static System.Array compuntrname;
		public static System.Array IISSiteName;
		public static string VirtualDir;
		public static System.Array IISInstance;
		public static CSWebService Ctlgwebsvr;
		public static CSWebService Mktgwebsvr;
        public static CSWebService Profwebsvr;
        public static CSWebService Ordrwebsvr;
		public static System.Windows.Forms.TextBox Status;
		public static bool cmdLine = false;
		public static string scurityFilePath = string.Empty;
		private static XmlDocument xmldoc = new XmlDocument();

		public CommerceSecurityInfo()
		{
			//
		}

		static CommerceSecurityInfo()
		{
			CommerceSecurityInfo._forms = new Hashtable();
		}
 
		[STAThread]
		private static void Main(string[] args)
		{
			CommerceSecurityInfo.Log("================================");
			CommerceSecurityInfo.Log("Commerce Server Security Starting...");
			
			if(!CommerceSecurityInfo.isCurrentUserAdmin())
			{

				CommerceSecurityInfo.Log("FAIL: Current user not an administrator...");
				CommerceSecurityInfo.CloseAll();
			}
			else
			{
				if(args.Length>0)
				{
					AllocConsole();
					
					CommerceSecurityInfo.scurityFilePath = args[0].ToString();
					CommerceSecurityInfo.cmdLine = true;

					CommerceSecurityInfo.LoadSecurityFile();
					CommerceSecurityInfo.InitCmdLine();
					
					//FreeConsole();
				}
				else
				{
                    CommerceSecurityInfo.InitForms();
					Application.Run((Form) CommerceSecurityInfo.Forms["Welcome"]);
				}
			}
			
		}
 
		private static bool isCurrentUserAdmin()
		{
			AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
			WindowsPrincipal principal = (WindowsPrincipal)Thread.CurrentPrincipal;
			WindowsIdentity identity = (WindowsIdentity)principal.Identity;

			return principal.IsInRole(WindowsBuiltInRole.Administrator);
		}

		public static void LoadSecurityFile()
		{
			xmldoc.Load(scurityFilePath);
			
			SiteName = xmldoc.SelectNodes("CommerceSecurityData/CommerceSiteInfo").Item(0).Attributes.GetNamedItem("SiteName").InnerText;
			CommerceSecurityInfo.ary = (System.Array)CommerceSecurityInfo.sitecfg.GetAppsInSite(ref CommerceSecurityInfo.SiteName);
			CommerceSecurityInfo.sitecfg.Initialize(CommerceSecurityInfo.SiteName);

			Domain = xmldoc.SelectNodes("CommerceSecurityData/UserInfo").Item(0).Attributes.GetNamedItem("Domain").InnerText;
			Password = xmldoc.SelectNodes("CommerceSecurityData/UserInfo").Item(0).Attributes.GetNamedItem("Password").InnerText;
			Username = xmldoc.SelectNodes("CommerceSecurityData/UserInfo").Item(0).Attributes.GetNamedItem("UserName").InnerText;

			ApplicationPoolName = xmldoc.SelectNodes("CommerceSecurityData/ApplicationPoolInfo").Item(0).Attributes.GetNamedItem("ApplicationPoolName").InnerText;
			NewApplicationPool = Convert.ToBoolean(xmldoc.SelectNodes("CommerceSecurityData/ApplicationPoolInfo").Item(0).Attributes.GetNamedItem("NewApplicationPool").InnerText);

			CommerceSecurityInfo.Ctlgwebsvr = new CSWebService(WebServiceType.catalogWebService);
			CommerceSecurityInfo.Mktgwebsvr = new CSWebService(WebServiceType.marketingWebService);
            CommerceSecurityInfo.Profwebsvr = new CSWebService(WebServiceType.profilesWebService);
            CommerceSecurityInfo.Ordrwebsvr = new CSWebService(WebServiceType.ordersWebService);

			CommerceSecurityInfo.setRoles(CommerceSecurityInfo.Ctlgwebsvr);
			CommerceSecurityInfo.setRoles(CommerceSecurityInfo.Mktgwebsvr);
            CommerceSecurityInfo.setRoles(CommerceSecurityInfo.Profwebsvr);
            CommerceSecurityInfo.setRoles(CommerceSecurityInfo.Ordrwebsvr);
		}

		public static string GenerateSecurityFile()
		{
			StringBuilder sb = new StringBuilder();
			sb.Append("<CommerceSecurityData>\r\n");
			
			sb.Append("  <CommerceSiteInfo SiteName=\""+SiteName+"\" />\r\n");
			sb.Append("<UserInfo");
			sb.Append(" UserName=\""+Username+"\" Password=\""+Password+"\" Domain=\""+Domain+"\"");
			sb.Append(" />\r\n");
		
			sb.Append("  <ApplicationPoolInfo");
			sb.Append(" NewApplicationPool=\""+NewApplicationPool.ToString()+"\" ApplicationPoolName=\""+ApplicationPoolName+"\"");
			sb.Append(" />\r\n");

            if (CatalogWebServiceRole!=null)
                SetupWebService(sb, "CatalogWebServiceInfo", CatalogWebServiceRole.Tables[0]);
            if (MarketingWebServiceRole != null)
                SetupWebService(sb, "MarketingWebServiceInfo", MarketingWebServiceRole.Tables[0]);
            if (OrdersWebServiceRole != null)
                SetupWebService(sb, "OrdersWebServiceInfo", OrdersWebServiceRole.Tables[0]);
            if (ProfilesWebServiceRole != null)
                SetupWebService(sb, "ProfilesWebServiceInfo", ProfilesWebServiceRole.Tables[0]);

			sb.Append("</CommerceSecurityData>");
			return sb.ToString();
		}

        public static void SetupWebService(StringBuilder sb, string webServiceInfo, DataTable dt)
        {
            sb.Append("  <");
            sb.Append(webServiceInfo);
            sb.Append(">\r\n");
            sb.Append("    <Roles>\r\n");
            foreach (DataRow row in dt.Rows)
            {
                sb.Append("      <Role RoleName=\"" + row["Role"].ToString() + "\" RoleValue=\"" + row["User"].ToString() + "\"/>\r\n");
            }
            sb.Append("    </Roles>\r\n");
            sb.Append("  </");
            sb.Append(webServiceInfo);
            sb.Append(">\r\n");
        }

		public static string SetupDir
		{
			get
			{
				return Application.StartupPath;
			}
		}

		public static void Log(string logString)
		{
			string text1 = Path.Combine(CommerceSecurityInfo.SetupDir, "Security.log");
			StreamWriter writer1 = File.AppendText(text1);
			writer1.WriteLine(string.Format("[{0}] {1}", DateTime.Now, logString));
			writer1.Close();
		}
 
		public static void SetStatus(string statusString)
		{
			if(!cmdLine)
			{
				Status.Text = Status.Text+statusString+"\r\n";
				Status.SelectionStart = Status.Text.Length;
				Status.ScrollToCaret();
				Status.Refresh();
			}
			else
			{
				Console.WriteLine(statusString);
			}
		}

		public unsafe static string GetErrorMessage(int errorCode)
		{
			int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
			int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
			int FORMAT_MESSAGE_FROM_SYSTEM  = 0x00001000;

			int messageSize = 255;
			String lpMsgBuf = "";
			int dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;

			IntPtr ptrlpSource = IntPtr.Zero;
			IntPtr prtArguments = IntPtr.Zero;
        
			int retVal = FormatMessage(dwFlags, ref ptrlpSource, errorCode, 0, ref lpMsgBuf, messageSize, &prtArguments);
			if (0 == retVal)
			{
				throw new Exception("Failed to format message for error code " + errorCode + ". ");
			}

			return lpMsgBuf;
		}

		public static bool LogonWithCredentials(string userName, string password, string domain)
		{
			const int LOGON32_PROVIDER_DEFAULT = 0;
			//This parameter causes LogonUser to create a primary token.
			const int LOGON32_LOGON_INTERACTIVE = 2;

			IntPtr tokenHandle = new IntPtr(0);
			IntPtr dupeTokenHandle = new IntPtr(0);

			tokenHandle = IntPtr.Zero;
			dupeTokenHandle = IntPtr.Zero;

			// Call LogonUser to obtain a handle to an access token.
			bool retVal = LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle);
			Log("logon for "+userName+" was successful ");
			return retVal;
		}

		public static void CloseAll()
		{
			Application.Exit();
		}

		public static Hashtable Forms
		{
			get
			{
				return CommerceSecurityInfo._forms;
			}
		}
 
		public static void InitCmdLine()
		{

			CommerceSecurityInfo.ApplyUser();

			if (false == CommerceSecurityInfo.LogonWithCredentials(CommerceSecurityInfo.Username, CommerceSecurityInfo.Password, CommerceSecurityInfo.Domain))
			{
				int ret = Marshal.GetLastWin32Error();
				string error = "LogonUser failed with error code: "+ret+ "Error Message: "+CommerceSecurityInfo.GetErrorMessage(ret);
				CommerceSecurityInfo.Log(error);
				CommerceSecurityInfo.SetStatus("==================================");
				CommerceSecurityInfo.SetStatus(error);
				CommerceSecurityInfo.SetStatus("==================================");
			}
			else
			{
				CommerceSecurityInfo.ApplyIISApplicatonPool();
				CommerceSecurityInfo.ApplyCatalogWebService();
				CommerceSecurityInfo.ApplyMarketingWebService();
                CommerceSecurityInfo.ApplyProfilesWebService();
                CommerceSecurityInfo.ApplyOrdersWebService();
				CommerceSecurityInfo.ApplyUserToDatabaseRoles();
				CommerceSecurityInfo.ApplyUserToCOMPlus();
				CommerceSecurityInfo.SetStatus("Done");
			}
		}

		public static void ApplyUser()
		{
			CommerceSecurityInfo.Log("START: ApplyUser");
			string domain = CommerceSecurityInfo.Domain;
			string adsiUser = CommerceSecurityInfo.Username;

            if (!CommerceSecurityInfo.UserExists(domain, adsiUser))
            {
                CommerceSecurityInfo.CreateUserAccount(domain, adsiUser, CommerceSecurityInfo.Password);
                CommerceSecurityInfo.Log("INFO: User created");
            }
            else
            {
                // add user to IIS_WP
                DirectoryEntry directoryEntry = new DirectoryEntry("WinNT://" + domain);
                DirectoryEntry newUser = directoryEntry.Children.Find(adsiUser, "user");
                AddUserToIISWPG(directoryEntry, newUser);
            }
			CommerceSecurityInfo.Log("END: ApplyUser");
		}

		public static void ApplyIISApplicatonPool()
		{
			CommerceSecurityInfo.Log("START: ApplyIISApplicatonPool");
			string domain = CommerceSecurityInfo.Domain;
			if(CommerceSecurityInfo.NewApplicationPool)
			{
				CommerceSecurityInfo.CreateAppPool(domain, CommerceSecurityInfo.ApplicationPoolName, CommerceSecurityInfo.Username, CommerceSecurityInfo.Password);
				CommerceSecurityInfo.Log("INFO: Application Pool created");
			}
			else
			{
				CommerceSecurityInfo.SetAppPool(domain, CommerceSecurityInfo.ApplicationPoolName, CommerceSecurityInfo.Username, CommerceSecurityInfo.Password);
				CommerceSecurityInfo.SetStatus("Applied "+domain+"\\"+CommerceSecurityInfo.Username+" to " +CommerceSecurityInfo.ApplicationPoolName+" Application Pool.");
				CommerceSecurityInfo.Log("INFO: Used existing Application Pool");
			}
			CommerceSecurityInfo.AssignVDirsToAppPool(CommerceSecurityInfo.ApplicationPoolName);
			CommerceSecurityInfo.SetFolderPermissions();
			CommerceSecurityInfo.Log("END: ApplyIISApplicatonPool");
		}

		public static void ApplyCatalogWebService()
		{
			CommerceSecurityInfo.Log("START: ApplyCatalogWebService");
			if(CommerceSecurityInfo.CatalogWebServiceRole!=null || CommerceSecurityInfo.CatalogWebServiceRole.Tables[0].Rows.Count < 0)
			{
				CommerceSecurityInfo.AddUserToAZRole(CommerceSecurityInfo.CatalogWebServiceRole, CommerceSecurityInfo.Ctlgwebsvr);
			}
			CommerceSecurityInfo.Log("END: ApplyCatalogWebService");
		}

		public static void ApplyMarketingWebService()
		{
			CommerceSecurityInfo.Log("START: ApplyMarketingWebService");
			if(CommerceSecurityInfo.MarketingWebServiceRole!=null || CommerceSecurityInfo.MarketingWebServiceRole.Tables[0].Rows.Count < 0)
			{
				CommerceSecurityInfo.AddUserToAZRole(CommerceSecurityInfo.MarketingWebServiceRole, CommerceSecurityInfo.Mktgwebsvr);
			}
			CommerceSecurityInfo.Log("END: ApplyMarketingWebService");
		}

        public static void ApplyOrdersWebService()
        {
            CommerceSecurityInfo.Log("START: ApplyOrdersWebService");
            if (CommerceSecurityInfo.OrdersWebServiceRole != null || CommerceSecurityInfo.OrdersWebServiceRole.Tables[0].Rows.Count < 0)
            {
                CommerceSecurityInfo.AddUserToAZRole(CommerceSecurityInfo.OrdersWebServiceRole, CommerceSecurityInfo.Ordrwebsvr);
            }
            CommerceSecurityInfo.Log("END: ApplyOrdersWebService");
        }

        public static void ApplyProfilesWebService()
        {
            CommerceSecurityInfo.Log("START: ApplyProfilesWebService");
            if (CommerceSecurityInfo.ProfilesWebServiceRole != null || CommerceSecurityInfo.ProfilesWebServiceRole.Tables[0].Rows.Count < 0)
            {
                CommerceSecurityInfo.AddUserToAZRole(CommerceSecurityInfo.ProfilesWebServiceRole, CommerceSecurityInfo.Profwebsvr);
            }
            CommerceSecurityInfo.Log("END: ApplyProfilesWebService");
        }

		public static void ApplyUserToDatabaseRoles()
		{
			CommerceSecurityInfo.Log("START: ApplyUserToDatabaseRoles");
			CommerceSecurityInfo.ApplyUserToDBRoles();
			CommerceSecurityInfo.Log("END: ApplyUserToDatabaseRoles");
		}

		public static void ApplyUserToCOMPlus()
		{
			CommerceSecurityInfo.Log("START: ApplyUserToCOMPlus");
			CommerceSecurityInfo.ApplyUserPermissionToCOMPlus();
			CommerceSecurityInfo.Log("END: ApplyUserToCOMPlus");
		}

		public static void InitForms()
		{
			CommerceSecurityInfo.Forms.Add("Welcome", new Welcome());
			CommerceSecurityInfo.Forms.Add("CommerceSite", new CommerceSite());
			CommerceSecurityInfo.Forms.Add("CommerceAccount", new CommerceAccount());
			CommerceSecurityInfo.Forms.Add("IISApplicationPool", new CreateIISApplicationPool());
			CommerceSecurityInfo.Forms.Add("CatalogWebService", new CatalogWebService());
			CommerceSecurityInfo.Forms.Add("MarketingWebService", new MarketingWebService());
            CommerceSecurityInfo.Forms.Add("OrdersWebService", new OrdersWebService());
            CommerceSecurityInfo.Forms.Add("ProfilesWebService", new ProfilesWebService());
			CommerceSecurityInfo.Forms.Add("SecureCommerceDB", new SecureCommerceDB());
			CommerceSecurityInfo.Forms.Add("Completed", new Completed());
		}
 
		public static CSWebService GetWebService(WebServiceType webServiceType)
		{
			try
			{
				return new CSWebService(webServiceType);
			}
			catch
			{
				CommerceSecurityInfo.Log("ERROR: Could not retrieve Commerce Web Service "+webServiceType.ToString());
				return null;
			}
		}

		public static void MoveToForm(string formName)
		{
			((Form) CommerceSecurityInfo.Forms[formName]).Visible = true;
		}

		public static void SetAppData(string name)
		{
			CommerceSecurityInfo.compuntrname = (System.Array)CommerceSecurityInfo.glb2.MakeArrayFromString(((ADODB._Recordset)(CommerceSecurityInfo.sitecfg.Fields[name].Value)).Fields["s_WebServerMachine"].Value);
			CommerceSecurityInfo.IISSiteName = (System.Array)CommerceSecurityInfo.glb2.MakeArrayFromString(((ADODB._Recordset)(CommerceSecurityInfo.sitecfg.Fields[name].Value)).Fields["s_WebServerName"].Value);
			CommerceSecurityInfo.VirtualDir = ((ADODB._Recordset)(CommerceSecurityInfo.sitecfg.Fields[name].Value)).Fields["s_VirtualRootName"].Value.ToString();
			CommerceSecurityInfo.IISInstance = (System.Array)CommerceSecurityInfo.glb2.MakeArrayFromString(((ADODB._Recordset)(CommerceSecurityInfo.sitecfg.Fields[name].Value)).Fields["s_WebServerInstance"].Value);
		}

		private static DataSet setRoles(CSWebService websvr)
		{
			DataSet ds = new DataSet();
			DataTable tbl = ds.Tables.Add();
			tbl.Columns.Add("Role");
			tbl.Columns.Add("User");

			if(cmdLine==true)
			{
				XmlNodeList nodeList; 
				if(websvr.WebServiceType==WebServiceType.catalogWebService)
				{
					nodeList = xmldoc.SelectNodes("CommerceSecurityData/CatalogWebServiceInfo/Roles").Item(0).ChildNodes;
				}
				else
				{
					nodeList = xmldoc.SelectNodes("CommerceSecurityData/MarketingWebServiceInfo/Roles").Item(0).ChildNodes;
				}

				for(int i = 0; i < nodeList.Count; i++)
				{
					DataRow dr = tbl.NewRow();
					dr["Role"] = nodeList.Item(i).Attributes.Item(0).InnerText;
					dr["User"] = nodeList.Item(i).Attributes.Item(1).InnerText;
					tbl.Rows.Add(dr);
				}
			}
			else
			{
				foreach(string roleName in websvr.AzManRoles)
				{
					DataRow dr = tbl.NewRow();
					dr["Role"] = roleName;
					dr["User"] = CommerceSecurityInfo.Domain+"\\"+CommerceSecurityInfo.Username;
					tbl.Rows.Add(dr);
				}
			}

			switch(websvr.WebServiceType)
			{
				case WebServiceType.catalogWebService:
					CatalogWebServiceRole = ds;
					break;
				case WebServiceType.marketingWebService:
					MarketingWebServiceRole = ds;
					break;
                case WebServiceType.ordersWebService:
                    OrdersWebServiceRole = ds;
                    break;
                case WebServiceType.profilesWebService:
                    ProfilesWebServiceRole = ds;
                    break;
			}

			return ds;
		}

		public static void SetAzManDataGrid(CSWebService websvr, DataGrid dtGrdRoles, BindingContext dindCtx)
		{
			DataSet ds = setRoles(websvr);
		
			DataGridTableStyle dgStyle = new DataGridTableStyle();
			dgStyle.AllowSorting = false;
			dgStyle.MappingName = "Table1";
			DataGridTextBoxColumn DisplayName = new DataGridTextBoxColumn();
			DisplayName.MappingName = "Role";
			DisplayName.HeaderText = "Role";
			DisplayName.Width = 200;
			DisplayName.ReadOnly = true;
			dgStyle.GridColumnStyles.Add(DisplayName);
			// Add a second column style.
			DataGridColumnStyle Value = new DataGridTextBoxColumn();
			Value.MappingName = "User";
			Value.HeaderText = "User";
			Value.Width = 200;
			Value.ReadOnly = false;
			dgStyle.GridColumnStyles.Add(Value);
			dtGrdRoles.TableStyles.Add(dgStyle);
			// disallow new rows from being created
			dtGrdRoles.DataSource = ds.Tables[0];
			CurrencyManager cm = (CurrencyManager)dindCtx[dtGrdRoles.DataSource, dtGrdRoles.DataMember];
			((DataView)cm.List).AllowNew = false;
			((DataView)cm.List).AllowDelete = false;	
		}

		public static bool UserExists(string targetMachine, string userLogin)
		{
			try
			{
				DirectoryEntry entry2 = new DirectoryEntry("WinNT://" + targetMachine);
				entry2.Children.Find(userLogin, "user");
				CommerceSecurityInfo.Log("INFO: User already exists");
				SetStatus(userLogin+" already exists in "+targetMachine+" server.");
				return true;
			}
			catch(Exception ex)
			{
				if(ex.Message!="The user name could not be found.")
				{
					CommerceSecurityInfo.Log("FAIL: "+ex.Message);
				}
				return false;
			}
		}

		public static void CreateUserAccount(string targetMachine, string userLogin, string userPassword)
		{
			try
			{
				DirectoryEntry newUser;
				DirectoryEntry directoryEntry = new DirectoryEntry("WinNT://" + targetMachine);

				newUser = directoryEntry.Children.Add(userLogin, "user");
				newUser.Properties["description"].Add("User Created for Securing "+ SiteName +" Site.");
				newUser.Properties["userFlags"].Add(0x200);
				newUser.Properties["userFlags"].Add(0x10000);
				newUser.Properties["userFlags"].Add(0x40);
				object[] objArray1 = new object[1] { userPassword } ;
				newUser.Invoke("SetPassword", objArray1);
				newUser.CommitChanges();

				SetStatus(userLogin+" user was created in "+targetMachine+" server.");
				
				AddUserToIISWPG(directoryEntry, newUser);
			}
			catch (Exception ex)
			{
				CommerceSecurityInfo.Log("FAIL: "+ex.Message);
			}
		}
		
		private static void AddUserToIISWPG(DirectoryEntry obDirEntry, DirectoryEntry adsiUser)
		{
			//Add  the user to the IIS_WPG and User groups
			DirectoryEntry grp = obDirEntry.Children.Find("IIS_WPG", "group");
			try
			{
				if (grp != null)
				{
					grp.Invoke("Add", new object[]{ adsiUser.Path.ToString()});
					CommerceSecurityInfo.Log("INFO: User added to IIS_WPG group");
				}
				grp.CommitChanges();
			}
			catch (Exception ex)
			{
				CommerceSecurityInfo.Log("FAIL: "+ex.Message);
			}
		}

		public static void CreateAppPool(string metabaseSystem, string appPoolName, string userName, string password)
		{
			try
			{
				DirectoryEntry apppools = getApplicationPool(metabaseSystem);
				DirectoryEntry newpool = apppools.Children.Add(appPoolName, "IIsApplicationPool");
				SetAppPool(newpool, userName, password);
				SetStatus(appPoolName+" application pool was created.");
				CommerceSecurityInfo.Log("INFO: Created Application Pool");
			}
			catch (Exception ex)
			{
				CommerceSecurityInfo.Log("FAIL: "+ex.Message);
			}
		}

		private static DirectoryEntry getApplicationPool(string metabaseSystem)
		{
			string metabasePath = "IIS://"+metabaseSystem+"/W3SVC/AppPools";
			try
			{
				return new DirectoryEntry(metabasePath);
			}
			catch (Exception ex)
			{
				CommerceSecurityInfo.Log("FAIL: "+ex.Message);
				return null;
			}
		}

		public static void SetAppPool(string metabaseSystem, string appPoolName, string userName, string password)
		{
			try
			{
				DirectoryEntry apppools = getApplicationPool(metabaseSystem);
				DirectoryEntry newpool = apppools.Children.Find(appPoolName, "IIsApplicationPool");
				SetAppPool(newpool, userName, password);
			}
			catch(Exception ex)
			{
				CommerceSecurityInfo.Log("FAIL: "+ex.Message);
			}
		}

		public static void SetAppPool(DirectoryEntry appPool, string userName, string password)
		{
			try
			{
				appPool.Properties["WAMUserName"].Value = userName;
				appPool.Properties["WAMUserPass"].Value = password;
				appPool.Properties["AppPoolIdentityType"].Value = "3";
				appPool.CommitChanges();
			}
			catch(Exception ex)
			{
				CommerceSecurityInfo.Log("FAIL: "+ex.Message);
			}
		}

		public static void AssignVDirsToAppPool(string appPoolName)
		{
			foreach(string name in CommerceSecurityInfo.ary)
			{
				SetAppData(name);

				string metabasePath = "IIS://"+compuntrname.GetValue(0).ToString()+"/W3SVC/"+IISInstance.GetValue(0)+"/Root/"+VirtualDir;

				try
				{
					DirectoryEntry vDir = new DirectoryEntry(metabasePath);
					string className = vDir.SchemaClassName.ToString();
					if (className.EndsWith("VirtualDir"))
					{
						object[] param = { 0, appPoolName, true };
						vDir.Invoke("AppCreate3", param);
						vDir.Properties["AppIsolated"][0] = "2";
					}
					else
					{
						CommerceSecurityInfo.Log("FAIL: The Application "+name+" was not a virtual directory");
					}
				}
				catch (Exception ex)
				{
					CommerceSecurityInfo.Log("FAIL: "+ex.Message);
				}
			}
		}

		public static void AddUserToAZRole(DataSet Roles, CSWebService websvr)
		{
			// get the file path
			AzAuthorizationStore AzManstore = new AzAuthorizationStoreClass();
			AzManstore.Initialize(0, @"msxml://"+websvr.AzManPath, null);
			string application = string.Empty;
			if(websvr.WebServiceType == WebServiceType.catalogWebService)
			{
                application = "CatalogandInventorySystem";
				SetStatus("Applying Catalog Web Service Authorization Manager roles");
			}
			else if (websvr.WebServiceType == WebServiceType.marketingWebService)
			{
                application = "MarketingSystem";
				SetStatus("Applying Marketing System Web Service Authorization Manager roles");
			}
            else if (websvr.WebServiceType == WebServiceType.profilesWebService)
			{
                application = "ProfileSystem";
				SetStatus("Applying Profile System Web Service Authorization Manager roles");
			}
            else if (websvr.WebServiceType == WebServiceType.ordersWebService)
			{
                application = "OrderSystem";
				SetStatus("Applying Order System Web Service Authorization Manager roles");
			}
			IAzApplication app = AzManstore.OpenApplication(application, null);

			// get role and set user
			foreach(DataRow role in Roles.Tables[0].Rows)
			{
				try
				{
					IAzRole azRole = app.OpenRole(role["Role"].ToString(), null);
					azRole.AddMemberName(role["User"].ToString(),null);
					azRole.Submit(0, null);
					SetStatus("     Applied "+role["User"].ToString()+" to "+role["Role"].ToString()+" Authorization Manager");
				}
				catch(Exception ex)
				{
					CommerceSecurityInfo.Log("FAIL: "+ex.Message);
				}
			}

			// may need this there is a bug with AzMan
			// Marshal.ReleaseComObject(AzManstore);
		}

		private static void setPermissionToFolder(string fileObject, ManagementObject newACEUser)
		{
			using(ManagementObject lfs = new ManagementObject(@"Win32_LogicalFileSecuritySetting.Path=" + "'" + fileObject + "'"))
			{
				ManagementBaseObject outParams = lfs.InvokeMethod("GetSecurityDescriptor", null, null);
			
				if (((uint)(outParams.Properties["ReturnValue"].Value)) == 0) // if success
				{
					ManagementBaseObject secDescriptor = ((ManagementBaseObject)(outParams.Properties["Descriptor"].Value));

					ManagementBaseObject[] dacl = ((ManagementBaseObject[])(secDescriptor.Properties["Dacl"].Value));
					ManagementBaseObject[] newAces = new ManagementBaseObject[dacl.Length+1]; // {newACEUser};
				
					int i=0;
					foreach(ManagementBaseObject mbo in dacl)
					{
						newAces[i] = mbo;
						i++;
					}
				
					newAces[i++] = newACEUser;

					secDescriptor.Properties["Dacl"].Value = newAces;

					object[] args = new object[] {secDescriptor};

					lfs.InvokeMethod("SetSecurityDescriptor", args);
				}
			}
		}

		private static ManagementObject getACEUser(object AceFlags, object AceType, object AccessMask)
		{
			ManagementClass win32Trustee = new ManagementClass(@"Win32_Trustee");
			ManagementClass win32Ace = new ManagementClass(@"Win32_ACE");
			ManagementObject newTrusteeUser = win32Trustee.CreateInstance();
			ManagementObject newACEUser = win32Ace.CreateInstance();
			newTrusteeUser["Name"] = Username;
			newACEUser["Trustee"] = newTrusteeUser;
			
			newACEUser["AceFlags"] = AceFlags;
			newACEUser["AceType"] = AceType;
			newACEUser["AccessMask"] = AccessMask;

			return newACEUser;
		}

		private static void setNETFolderPermissions()
		{
			string clrPath = RuntimeEnvironment.GetRuntimeDirectory();
			string aspnetPath = null;
			if (clrPath.EndsWith(@"\")) 
			{
				aspnetPath = clrPath + @"Temporary ASP.NET Files";
			}
			else
			{
				aspnetPath = clrPath + @"\Temporary ASP.NET Files";
			}
			if (Directory.Exists(aspnetPath) == false)
			{
				CommerceSecurityInfo.Log("FAIL: "+aspnetPath+" path was not found");
			}
			
			setPermissionToFolder(aspnetPath, getACEUser(3, 0, 1179785));

			SelectQuery query = new SelectQuery("Win32_Environment", "UserName=\"<SYSTEM>\"");
			ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);

			foreach (ManagementBaseObject envVar in searcher.Get()) 
			{
				if(envVar["Name"].ToString()=="TEMP")
				{
					string tempDir = Environment.ExpandEnvironmentVariables(envVar["VariableValue"].ToString());
					setPermissionToFolder(tempDir, getACEUser(0, 0, 1179785));
					break;
				}
			}
		}

		private static void setCSApplicationFolderPermissions()
		{
			foreach(string name in ary)
			{
				SetAppData(name);

				string WebServicepath = null;

				if(VirtualDir!="/")
				{
					WebServicepath = "IIS://"+compuntrname.GetValue(0).ToString()+"/W3SVC/"+IISInstance.GetValue(0)+"/Root/"+VirtualDir;
				}
				else
				{
					WebServicepath = "IIS://"+compuntrname.GetValue(0).ToString()+"/W3SVC/"+IISInstance.GetValue(0)+"/Root";
				}

				DirectoryEntry iis = new DirectoryEntry(WebServicepath);
				string iisPath = iis.Properties["Path"].Value.ToString();

				setPermissionToFolder(iisPath, getACEUser(19, 0, 1179817));
			}
		}

		private static void setAzManStoreFilePermissions()
		{
			setPermissionToFolder(CommerceSecurityInfo.Ctlgwebsvr.AzManPath, getACEUser(0, 0, 1180095));
			setPermissionToFolder(CommerceSecurityInfo.Mktgwebsvr.AzManPath, getACEUser(0, 0, 1180095));
            setPermissionToFolder(CommerceSecurityInfo.Ordrwebsvr.AzManPath, getACEUser(0, 0, 1180095));
            setPermissionToFolder(CommerceSecurityInfo.Profwebsvr.AzManPath, getACEUser(0, 0, 1180095));
		}

		public static void SetFolderPermissions()
		{
			setNETFolderPermissions();
			setAzManStoreFilePermissions();
			setCSApplicationFolderPermissions();
		}

        public static string GetSetupLogPath()
        {
            RegistryKey key1 = null;
            if (IntPtr.Size == 4)
            {
                key1 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Commerce Server 2007", false);
            }
            else if (IntPtr.Size == 8)
            {
                key1 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Commerce Server 2007", false);
            }
            if (key1 == null)
            {
                throw new NotSupportedException();
            }
            byte[] buffer2 = (byte[])key1.GetValue("ADMINDBPS");
            byte[] buffer1 = ProtectedData.Unprotect(buffer2, null, DataProtectionScope.LocalMachine);
            return new string(Encoding.Unicode.GetChars(buffer1));
        }

		private static string getAdminConnctionString()
		{
            string conStr = GetSetupLogPath();
			return conStr.Replace("Provider=SQLOLEDB.1;", "").Replace("Provider=SQLOLEDB;","");
		}

		private static string getConnectionString(string csResource, string conString)
		{
			SiteConfigReadOnlyFreeThreaded sitecfg = new SiteConfigReadOnlyFreeThreaded();
			sitecfg.Initialize(SiteName);

			string conStr = (((ADODB._Recordset)(sitecfg.Fields[csResource].Value)).Fields[conString].Value).ToString();

			return conStr.Replace("Provider=SQLOLEDB.1;", "").Replace("Provider=SQLOLEDB;","");
		}

		private static void executeSQL(string[] queryStr, string connStr)
		{
			SqlConnection sqlConnection = new SqlConnection(connStr);
			sqlConnection.Open();

			foreach(string sql in queryStr)
			{
                try
                {
                    SqlCommand sqlCommand = new SqlCommand(sql, sqlConnection);
                    int returnCmd = sqlCommand.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    CommerceSecurityInfo.Log("FAIL: " + ex.Message);
                }
			}

            sqlConnection.Close();
		}

		private static string[] readFile(string path)
		{
			StreamReader sr = new StreamReader(path);
			string file = sr.ReadToEnd();
			file = file.Replace("GO","|");

			return file.Split('|');
		}

		public static void ApplyUserToDBRoles()
		{
			string user = "'"+Domain+@"\"+Username+"'";
			// add user to MSCS_Admin db
			string[] queryAdminStr = new string[5];
            queryAdminStr[0] = "CREATE LOGIN [" + Domain + @"\" + Username + "] FROM WINDOWS WITH DEFAULT_DATABASE=[master]";
            queryAdminStr[1] = "EXEC sp_grantdbaccess "+user+", "+user;
			queryAdminStr[2] = "EXEC sp_grantlogin N"+user;
			queryAdminStr[3] = "EXEC sp_addrolemember 'db_datareader', " + user;
            queryAdminStr[4] = "EXEC sp_addrolemember 'admin_reader_role', " + user;
            executeSQL(queryAdminStr, getAdminConnctionString());
			SetStatus("Granted loging to "+user+" in Admin Database");
			SetStatus("Applied " + user + " to db_datareader Database Role");
            SetStatus("Applied " + user + " to admin_reader_role Database Role");
			CommerceSecurityInfo.Log("INFO: Added user to Admin Database roles");
            CommerceSecurityInfo.Log("INFO: Applied user to db_datareader Database roles");
            CommerceSecurityInfo.Log("INFO: Applied user to admin_reader_role Database roles");

            // add user to msdb db for the DTS Import process
            string[] querymsdbStr = new string[6];
            querymsdbStr[0] = "EXEC sp_grantdbaccess " + user + ", " + user;
            querymsdbStr[1] = "EXEC sp_grantlogin N" + user;
            querymsdbStr[2] = "EXEC sp_addrolemember 'db_datareader', " + user;
            querymsdbStr[3] = "EXEC sp_addrolemember 'db_dtsadmin', " + user;
            querymsdbStr[4] = "EXEC sp_addrolemember 'db_dtsltduser', " + user;
            querymsdbStr[5] = "EXEC sp_addrolemember 'db_dtsoperator', " + user;
            string msdbConstr = getAdminConnctionString();
            int msdbiPos = msdbConstr.IndexOf("Initial Catalog=") + 16;
            int msdbePos = msdbConstr.IndexOf(";", msdbiPos);
            string msdbolddb = msdbConstr.Substring(msdbiPos, msdbePos - msdbiPos);
            msdbConstr = msdbConstr.Replace(msdbolddb, "msdb");
            executeSQL(querymsdbStr, msdbConstr);
            SetStatus("Granted loging to " + user + " in msdb Database");
            SetStatus("Applied " + user + " to db_datareader Database Role");
            SetStatus("Applied " + user + " to db_dtsadmin Database Role");
            SetStatus("Applied " + user + " to db_dtsltduser Database Role");
            SetStatus("Applied " + user + " to db_dtsoperator Database Role");
            CommerceSecurityInfo.Log("INFO: Added user to msdb Database roles");
            CommerceSecurityInfo.Log("INFO: Applied user to db_datareader Database roles");
            CommerceSecurityInfo.Log("INFO: Applied user to db_dtsadmin Database roles");
            CommerceSecurityInfo.Log("INFO: Applied user to db_dtsltduser Database roles");
            CommerceSecurityInfo.Log("INFO: Applied user to db_dtsoperator Database roles");

			foreach(Field fld in CommerceSecurityInfo.sitecfg.Fields)
			{
				switch(fld.Name.ToString())
				{
					case "Direct Mail":
                        // Not implemented
						break;
					case "Global Data Warehouse":
                        // Not implemented
						break;
					case "Site Data Warehouse":
                        // Not implemented
                        break;
					case "Transactions":
						string[] queryTransactionStr = new string[5];
                        queryTransactionStr[0] = "EXEC sp_grantdbaccess "+user+", "+user;
						queryTransactionStr[1] = "EXEC sp_grantlogin N"+user;
						queryTransactionStr[2] = "EXEC sp_addrolemember 'Orders_Management', " + user;
                        queryTransactionStr[3] = "EXEC sp_addrolemember 'Orders_Runtime', " + user;
                        queryTransactionStr[4] = "EXEC sp_addrolemember 'db_datareader', " + user;
						executeSQL(queryTransactionStr, getConnectionString("Transactions","connstr_db_Transactions"));
						SetStatus("Granted loging to "+user+" in Transaction Resource");
                        SetStatus("Applied " + user + " to Orders_Management Database Role");
                        SetStatus("Applied " + user + " to Orders_Runtime Database Role");
                        SetStatus("Applied " + user + " to db_datareader Database Role");
						CommerceSecurityInfo.Log("INFO: Added user to Transactions roles");
						break;
					case "Transaction Config":
						string[] queryTransactionConfigStr = new string[5];
						queryTransactionConfigStr[0] = "EXEC sp_grantdbaccess "+user+", "+user;
 						queryTransactionConfigStr[1] = "EXEC sp_grantlogin N"+user;
						queryTransactionConfigStr[2] = "EXEC sp_addrolemember 'Orders_Runtime', " + user;
						queryTransactionConfigStr[3] = "EXEC sp_addrolemember 'Orders_Management', " + user;
                        queryTransactionConfigStr[4] = "EXEC sp_addrolemember 'db_datareader', " + user;
						executeSQL(queryTransactionConfigStr, getConnectionString("Transaction Config","connstr_db_TransactionConfig"));
						SetStatus("Granted loging to "+user+" in Transaction Config Resource");
                        SetStatus("Applied " + user + " to Orders_Runtime Database Role");
                        SetStatus("Applied " + user + " to Orders_Management Database Role");
                        SetStatus("Applied " + user + " to db_datareader Database Role");
						CommerceSecurityInfo.Log("INFO: Added user to Transaction Config roles");
						break;
                    case "Inventory":
                        // we are going to assume that the inventory is in the Product Catalog Database
                        //string[] queryCatalogStr = new string[2];
                        //queryInventoryStr[0] = "EXEC sp_grantdbaccess " + user + ", " + user;
                        //queryInventoryStr[1] = "EXEC sp_grantlogin N" + user;
                        //queryInventoryStr[2] = "EXEC sp_addrolemember '', " + user;

                        //executeSQL(queryCatalogStr, getConnectionString("Inventory", "connstr_db_inventory"));
                        //SetStatus("Granted loging to " + user + " in Inventory Resource");
                        //SetStatus("Applied " + user + " to  Database Role");
                        //CommerceSecurityInfo.Log("INFO: Added user to Inventory roles");
                        break;
                    case "Product Catalog":
						string[] queryCatalogStr = new string[11];
						queryCatalogStr[0] = "EXEC sp_grantdbaccess " + user + ", " + user;
						queryCatalogStr[1] = "EXEC sp_grantlogin N" + user;
                        queryCatalogStr[2] = "EXEC sp_addrolemember 'ctlg_CatalogWriterRole', " + user;
						queryCatalogStr[3] = "EXEC sp_addrolemember 'ctlg_catalogReaderRole', " + user;
                        queryCatalogStr[4] = "EXEC sp_addrolemember 'db_ddladmin', " + user;
                        queryCatalogStr[5] = "EXEC sp_addrolemember 'db_securityadmin', " + user;
						queryCatalogStr[6] = "EXEC sp_addrolemember 'Inventory_RuntimeRole', " + user;
                        queryCatalogStr[7] = "EXEC sp_addrolemember 'Inventory_ReaderRole', " + user;
                        queryCatalogStr[8] = "EXEC sp_addrolemember 'Inventory_WriterRole', " + user;
						queryCatalogStr[9] = "EXEC sp_addrolemember 'db_datareader', " + user;
                        queryCatalogStr[10] = "EXEC sp_addrolemember 'db_datawriter', " + user;
                        executeSQL(queryCatalogStr, getConnectionString("Product Catalog","connstr_db_Catalog"));
						SetStatus("Granted loging to " + user + " in Product Catalog Resource");
                        SetStatus("Applied " + user + " to ctlg_CatalogWriterRole Database Role");
                        SetStatus("Applied " + user + " to ctlg_catalogReaderRole Database Role");
                        SetStatus("Applied " + user + " to db_ddladmin Database Role");
                        SetStatus("Applied " + user + " to db_securityadmin Database Role");
                        SetStatus("Applied " + user + " to Inventory_RuntimeRole Database Role");
                        SetStatus("Applied " + user + " to Inventory_ReaderRole Database Role");
                        SetStatus("Applied " + user + " to Inventory_WriterRole Database Role");
                        SetStatus("Applied " + user + " to db_datareader Database Role");
                        SetStatus("Applied " + user + " to db_datawriter Database Role");
                        CommerceSecurityInfo.Log("INFO: Added user to Product Catalog roles");

                        // MSCS_CatalogScratch
						string[] queryCatalogScratchStr = new string[5];
						queryCatalogScratchStr[0] = "EXEC sp_grantdbaccess "+user+", "+user;
						queryCatalogScratchStr[1] = "EXEC sp_grantlogin N"+user;
                        queryCatalogScratchStr[2] = "EXEC sp_addrolemember 'db_ddladmin', " + user;
                        queryCatalogScratchStr[3] = "EXEC sp_addrolemember 'db_datareader', " + user;
                        queryCatalogScratchStr[4] = "EXEC sp_addrolemember 'db_datawriter', " + user;
						string ScratchConstr = getConnectionString("Product Catalog","connstr_db_Catalog");
						int iPos = ScratchConstr.IndexOf("Initial Catalog=")+16;
						int ePos = ScratchConstr.IndexOf(";", iPos);
						string olddb = ScratchConstr.Substring(iPos, ePos-iPos);
						ScratchConstr = ScratchConstr.Replace(olddb,"MSCS_CatalogScratch");
						executeSQL(queryCatalogScratchStr, ScratchConstr.Replace("Provider=SQLOLEDB.1;", "").Replace("Provider=SQLOLEDB;",""));
						SetStatus("Granted loging to "+user+" in Catalog Scratch database");
                        SetStatus("Applied " + user + " to db_ddladmin Database Role");
                        SetStatus("Applied " + user + " to db_datareader Database Role");
                        SetStatus("Applied " + user + " to db_datawriter Database Role");
						CommerceSecurityInfo.Log("INFO: Added user to Catalog Scratch database");
						break;
					case "Marketing":
                        // Marketing resource
						string[] queryMktgStr = new string[7];
						queryMktgStr[0] = "EXEC sp_grantdbaccess "+user+", "+user;
						queryMktgStr[1] = "EXEC sp_grantlogin N"+user;
                        queryMktgStr[2] = "EXEC sp_addrolemember 'mktg_MarketingService_role', " + user;
						queryMktgStr[3] = "EXEC sp_addrolemember 'mktg_promoCodeGenerator_role', " + user;
						queryMktgStr[4] = "EXEC sp_addrolemember 'mktg_runtime_role', " + user;
						queryMktgStr[5] = "EXEC sp_addrolemember 'db_datareader', " + user;
						queryMktgStr[6] = "EXEC sp_addrolemember 'mktg_directmailer_role', " + user;
                        executeSQL(queryMktgStr, getConnectionString("Marketing","connstr_db_Marketing"));
						SetStatus("Granted loging to " + user + " in Marketing Resource");
                        SetStatus("Applied " + user + " to mktg_MarketingService_role Database Role");
                        SetStatus("Applied " + user + " to mktg_promoCodeGenerator_role Database Role");
                        SetStatus("Applied " + user + " to mktg_runtime_role Database Role");
                        SetStatus("Applied " + user + " to db_datareader Database Role");
                        SetStatus("Applied " + user + " to mktg_directmailer_role Database Role");
                        SetStatus("Applied " + user + " to db_owner Database Role");
						CommerceSecurityInfo.Log("INFO: Added user to Marketing roles");

                        // Marketing list
                        string[] queryMarketingListStr = new string[4];
                        queryMarketingListStr[0] = "EXEC sp_grantdbaccess " + user + ", " + user;
                        queryMarketingListStr[1] = "EXEC sp_grantlogin N" + user;
                        queryMarketingListStr[2] = "EXEC sp_addrolemember 'db_datareader', " + user;
                        queryMarketingListStr[3] = "EXEC sp_addrolemember 'db_owner', " + user;
                        executeSQL(queryMarketingListStr, getConnectionString("Marketing", "connstr_db_Lists"));
                        SetStatus("Granted loging to " + user + " in Marketing List Resource");
                        SetStatus("Applied " + user + " to db_owner Database Role");
                        SetStatus("Applied " + user + " to db_owner Database Role");
                        CommerceSecurityInfo.Log("INFO: Added user to Marketing List roles");
						break;
					case "Biz Data Service":
						string[] queryProfilesStr = new string[7];
						queryProfilesStr[0] = "EXEC sp_grantdbaccess "+user+", "+user;
						queryProfilesStr[1] = "EXEC sp_grantlogin N"+user;
						queryProfilesStr[2] = "EXEC sp_addrolemember 'Profile_Reader', " + user;
						queryProfilesStr[3] = "EXEC sp_addrolemember 'Profile_Schema_Reader', " + user;
                        queryProfilesStr[4] = "EXEC sp_addrolemember 'Profile_Schema_Manager', " + user;
						queryProfilesStr[5] = "EXEC sp_addrolemember 'Profile_Runtime', " + user;
                        queryProfilesStr[6] = "EXEC sp_addrolemember 'db_datareader', " + user;
						executeSQL(queryProfilesStr, getConnectionString("Biz Data Service","s_BizDataStoreConnectionString"));
						SetStatus("Granted loging to "+user+" in Biz Data Service Resource");
                        SetStatus("Applied " + user + " to Profile_Reader Database Role");
                        SetStatus("Applied " + user + " to Profile_Schema_Reader Database Role");
                        SetStatus("Applied " + user + " to Profile_Schema_Manager Database Role");
                        SetStatus("Applied " + user + " to Profile_Runtime Database Role");
                        SetStatus("Applied " + user + " to db_datareader Database Role");
						CommerceSecurityInfo.Log("INFO: Added user to Biz Data Service roles");
						break;
				}
			}
		}

		public static void ApplyUserPermissionToCOMPlus()
		{
			COMAdminCatalogClass COMAdminctlg = new COMAdminCatalogClass();
			COMAdminctlg.Connect(System.Net.Dns.GetHostName());

			COMAdminCatalogCollection ctlgCollection = (COMAdminCatalogCollection)COMAdminctlg.GetCollection("Applications");
			ctlgCollection.Populate();

			foreach(COMAdminCatalogObject obj in ctlgCollection)
			{
				if(obj.Name.ToString()=="Commerce Server Config")
				{
					ICatalogCollection objRolesColl = (ICatalogCollection)ctlgCollection.GetCollection("Roles", obj.Key);
					objRolesColl.Populate();
					
					for(int j=0; objRolesColl.Count > j; j++)
					{
						COMAdminCatalogObject ctlgObj = (COMAdminCatalogObject)objRolesColl.get_Item(j);
						
						if(ctlgObj.Name.ToString()=="Web Users")
						{
							COMAdminCatalogCollection users = (COMAdminCatalogCollection)objRolesColl.GetCollection("UsersInRole", ctlgObj.Key);
							COMAdminCatalogObject user = (COMAdminCatalogObject)users.Add();
							user.set_Value("User", Domain+@"\"+Username);
							users.SaveChanges();
							SetStatus(Domain+@"\"+Username+" was added to Web Users COM+ role in Commerce Server Config object");
							CommerceSecurityInfo.Log("INFO: Applied user to Commerce Server Config COM+ Web User role");
							break;
						}
					}
				}
			}
		}
	}

	public enum WebServiceType
	{
		catalogWebService,
		marketingWebService,
        profilesWebService,
        ordersWebService
	}

	public class CSWebService
	{
		private string path = string.Empty;
		private WebServiceType webServiceType;
		private string[] roles;
		private AzAuthorizationStore AzManstore = new AzAuthorizationStoreClass();
		private IAzApplication app = null;

		public CSWebService(WebServiceType webSvcType)
		{
			webServiceType = webSvcType;
			loadWebSerivceObjects();
		}
		
		private void loadWebSerivceObjects()
		{
			foreach(string name in CommerceSecurityInfo.ary)
			{
				CommerceSecurityInfo.SetAppData(name);

				string WebServicepath = null;

				if(CommerceSecurityInfo.VirtualDir!="/")
				{
					// get the path with virtual directory
					WebServicepath = "IIS://"+CommerceSecurityInfo.compuntrname.GetValue(0).ToString()+"/W3SVC/"+CommerceSecurityInfo.IISInstance.GetValue(0)+"/Root/"+CommerceSecurityInfo.VirtualDir;
				}
				else
				{
					// get the root path
					WebServicepath = "IIS://"+CommerceSecurityInfo.compuntrname.GetValue(0).ToString()+"/W3SVC/"+CommerceSecurityInfo.IISInstance.GetValue(0)+"/Root";
				}

				DirectoryEntry iis = new DirectoryEntry(WebServicepath);
				string webcfg = iis.Properties["Path"].Value.ToString()+"\\web.Config";

				// make sure the file exists
				if(System.IO.File.Exists(webcfg))
				{
					XmlDocument xmldoc = new XmlDocument();
					xmldoc.Load(webcfg);

					string xmlPath = "/configuration/configSections/sectionGroup/section";
                    string webServiceName = xmldoc.SelectNodes(xmlPath).Item(xmldoc.SelectNodes(xmlPath).Count - 1).Attributes["name"].InnerText;
				
					if(webServiceName == webServiceType.ToString() && webServiceType.ToString() == "catalogWebService")
					{
						xmlPath = "configuration/CommerceServer/"+webServiceType.ToString();
						XmlNode xmlnode = xmldoc.SelectNodes(xmlPath).Item(0).Attributes.GetNamedItem("disableAuthorization");
						string disableAuthorization = string.Empty;
						if(xmlnode!=null)
						{
							disableAuthorization = xmldoc.SelectNodes(xmlPath).Item(0).Attributes["disableAuthorization"].InnerText;
						}
						if(disableAuthorization == null || disableAuthorization!="true")
						{
                            getRoles(xmldoc, "CatalogandInventorySystem", xmlPath, iis);
							break;
						}
					}
					else if(webServiceName == webServiceType.ToString() && webServiceType.ToString() == "marketingWebService")
					{
						xmlPath = "configuration/CommerceServer/"+webServiceType.ToString();
						XmlNode xmlnode = xmldoc.SelectNodes(xmlPath).Item(0).Attributes.GetNamedItem("disableAuthorization");
						string disableAuthorization = string.Empty;
						if(xmlnode!=null)
						{
							disableAuthorization = xmldoc.SelectNodes(xmlPath).Item(0).Attributes["disableAuthorization"].InnerText;
						}
						if(disableAuthorization == null || disableAuthorization!="true")
						{
                            getRoles(xmldoc, "MarketingSystem", xmlPath, iis);
							break;
						}
					}
                    else if (webServiceName == webServiceType.ToString() && webServiceType.ToString() == "ordersWebService")
                    {
                        xmlPath = "configuration/CommerceServer/" + webServiceType.ToString();
                        XmlNode xmlnode = xmldoc.SelectNodes(xmlPath).Item(0).Attributes.GetNamedItem("disableAuthorization");
                        string disableAuthorization = string.Empty;
                        if (xmlnode != null)
                        {
                            disableAuthorization = xmldoc.SelectNodes(xmlPath).Item(0).Attributes["disableAuthorization"].InnerText;
                        }
                        if (disableAuthorization == null || disableAuthorization != "true")
                        {
                            getRoles(xmldoc, "OrderSystem", xmlPath, iis);
                            break;
                        }
                    }
                    else if (webServiceName == webServiceType.ToString() && webServiceType.ToString() == "profilesWebService")
                    {
                        xmlPath = "configuration/CommerceServer/" + webServiceType.ToString();
                        XmlNode xmlnode = xmldoc.SelectNodes(xmlPath).Item(0).Attributes.GetNamedItem("disableAuthorization");
                        string disableAuthorization = string.Empty;
                        if (xmlnode != null)
                        {
                            disableAuthorization = xmldoc.SelectNodes(xmlPath).Item(0).Attributes["disableAuthorization"].InnerText;
                        }
                        if (disableAuthorization == null || disableAuthorization != "true")
                        {
                            getRoles(xmldoc, "ProfileSystem", xmlPath, iis);
                            break;
                        }
                    }
				}
			}
		}

		private void getRoles(XmlDocument xmldoc, string webServiceSystem, string xmlPath, DirectoryEntry iis)
		{
			string authorizationPolicyPath = xmldoc.SelectNodes(xmlPath).Item(0).Attributes["authorizationPolicyPath"].InnerText;
			path=iis.Properties["Path"].Value.ToString()+"\\"+authorizationPolicyPath;

			AzManstore.Initialize(0, @"msxml://"+path, null);
			app = AzManstore.OpenApplication(webServiceSystem, null);
			roles = new string[app.Roles.Count];

			for(int i=1; app.Roles.Count > i-1; i++)
			{
				roles[i-1] = ((IAzRole)app.Roles[i]).Name;
			}
		}

		public string AzManPath
		{
			get {return path;}
		}

		public string[] AzManRoles
		{
			get {return roles;}
		}

		public WebServiceType WebServiceType
		{
			get {return webServiceType;}
		}
	}
}